<template>
  <!-- 一个带搜索过滤框和表格的组件 -->
  <div class="book-list">
    <el-row class="book-list__head" type="flex" justify="center" align="center">
      <el-col :span="18">
        <slot name="head">
          <el-breadcrumb class="main-title">
            <el-breadcrumb-item>{{ title }}</el-breadcrumb-item>
          </el-breadcrumb>
        </slot>
      </el-col>
      <el-col :span="6">
        <!-- 新建按钮 -->
        <el-button
          v-if="!cutOperation.includes('create')"
          size="medium"
          type="primary"
          plain
          icon="el-icon-plus"
          @click="toCreate">
          新建
        </el-button>
      </el-col>
    </el-row>
    <!-- 搜索 -->
    <el-row class="search" type="flex" justify="end">
      <div class="search-form" @keyup.enter="handleSearch">
        <el-input v-model="searchValue" clearable placeholder="请输入内容" @keyup.enter="handleSearch">
          <el-select v-model="searchKey" slot="prepend" class="search-select" placeholder="请选择">
            <el-option label="主键 ID" value="_id"></el-option>
            <el-option
              v-for="(item, index) in searchOption"
              :key="index"
              :label="item.label"
              :value="item.key">
            </el-option>
          </el-select>
          <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
        </el-input>
      </div>
    </el-row>
    <!-- table -->
    <el-card v-loading="$store.state.loading">
      <el-table :loading="$store.state.loading" @sort-change="handleSort" class="table-list" :stripe="false"
                :data="tableDate">
        <slot name="tableRows"></slot>
        <!-- 操作列 -->
        <slot name="operationRows">
          <el-table-column min-width="110px">
            <template slot-scope="props">
              <i
                v-if="!cutOperation.includes('delete')"
                class="el-icon-delete operation-btn"
                title="删除"
                @click="del(props.row._id)">
              </i>
              <i
                v-if="!cutOperation.includes('edit')"
                class="el-icon-edit-outline operation-btn"
                title="编辑"
                @click="edit(props.row._id)">
              </i>
              <i
                v-if="!cutOperation.includes('view')"
                class="el-icon-view operation-btn"
                title="查看"
                @click="view(props.row)">
              </i>
              <i
                v-if="selectOperation.includes('export')"
                class="el-icon-download operation-btn"
                title="导出"
                @click="handleExport(props.row)">
              </i>
            </template>
          </el-table-column>
        </slot>
      </el-table>
    </el-card>

    <!-- 分页操作 -->
    <el-pagination
      v-if="count > 10"
      style="float: right; margin-top: 20px"
      background
      layout="prev, pager, next, sizes"
      :page-sizes="[10, 100, 200, 500]"
      :total="count"
      :current-page.sync="params._page"
      @size-change="handleSizeChange"
      @current-change="loadData">
    </el-pagination>
  </div>
</template>


<script>
  export default {
    name: 'leave-crud',
    props: {
      // 搜索选项
      searchOption: {
        type: Array,
        default: () => [],
      },
      title: {
        type: String,
        required: true,
      },
      // 数据源
      url: {
        type: String,
        required: true,
      },
      // 操作
      cutOperation: {
        type: Array,
        default: () => [],
      },
      selectOperation: {
        type: Array,
        default: () => [],
      },
    },
    data() {
      return {
        detailsVisible: false,
        tableDate: [],
        searchValue: '',
        searchKey: '_id',
        params: {
          _limit: 10,
          _page: 1,
        },
        count: 0,
        schema: {},
        record: {},
        hash: '',
      }
    },
    methods: {
      handleConfirm() {
        this.$refs.detailsForm.validate((valid) => {
          if (!valid) {
            return
          }
          // 检测变化项目
          const old = JSON.parse(this.hash)
          const $set = {}
          Object.keys(this.record).forEach((item) => {
            if (this.record[item] !== old[item]) {
              $set[item] = this.record[item]
            }
          })
          this.$httpPut(`${this.url}/${this.record._id}/update`, { $set }).then(() => {
            this.$message.success('更新成功')
            this.detailsVisible = false
            this.loadData()
          }).catch(this.handleError)
        })
      },
      handleError(error) {
        this.$message.error(error.message || '操作失败')
      },
      handleExport(row) {
        const data = {
          client_id: row._id,
          host: this.$store.state.user.host
            ? `${this.$store.state.user.host}:${this.$store.state.user.port || 7070}`
            : window.location.host,
          path: '/api/upstream_public',
          token: row.token,
          upType: row.upType,
          module: row.module,
          rate: row.rate,
        }
        const aTag = document.createElement('a')
        aTag.download = `${data.client_id}_${data.module.join('_')}_linux_.json`
        const blob = new Blob([JSON.stringify(data, null, 2)])
        aTag.href = URL.createObjectURL(blob)
        aTag.click()
      },
      toCreate() {
        this.$router.push(`${this.$route.path}/0?operation=create`)
      },
      edit(_id = '') {
        this.$router.push(`${this.url.replace('/list', '')}/${_id}?operation=edit`)
      },
      del(_id = '') {
        this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }).then(() => {
          this.$httpDelete(`${this.url}/${_id}`).then(() => {
            this.$message.success('删除成功！')
            this.loadData()
          }).catch((error) => {
            this.$message.error(`删除失败：${error.message}`)
          })
        }).catch(() => {
          console.log()
        })
      },
      handleSort(column) {
        delete this.params._desc
        delete this.params._asc
        if (column.order === 'descending') {
          this.params._desc = column.prop
        } else {
          this.params._asc = column.prop
        }
        this.loadData()
      },
      handleSearch() {
        if (!this.searchValue) {
          this.params = {
            _limit: this.params._limit,
            _page: this.params._page,
          }
          this.loadData()
          return
        }
        if (this.searchKey === '_id' && this.searchValue.length !== 24) {
          this.$message.error('主键 ID 非法')
          return
        }
        // 从第一页开始
        this.params._page = 1
        if (this.searchKey !== '_id') {
          this.params[`${this.searchKey}_like`] = this.searchValue
        } else {
          this.params._id_is = this.searchValue
        }
        this.loadData()
      },
      loadData() {
        this.$httpGet(this.url, this.params).then((response) => {
          this.count = response.data.meta.count || 0
          this.tableDate = response.data.items
          this.schema = response.data.schema
        }).catch((error) => {
          this.$message.error(error.message)
        })
      },
      handleSizeChange(size = 0) {
        this.params._limit = size
        this.loadData()
      },
      view(row) {
        this.record = row
        this.hash = JSON.stringify(this.record)
        this.detailsVisible = true
        this.$router.push(`${this.url}/${row._id}`)
      },
    },
    created() {
      this.loadData()
    },
    computed: {
      hashChanged() {
        return JSON.stringify(this.record) === this.hash
      },
    },
  }
</script>


<style lang="scss">
  .book-list {
    .book-list__head {
      margin: 12px auto;
      min-height: 47px;
      padding: 6px;
      border-bottom: 1px solid #e8e8e8;
      align-items: center;
    }
    .main-title {
      font-size: 20px;
    }
    .el-button {
      float: right;
    }
    .search {
      margin: 12px auto;
    }
    .operation-btn {
      font-size: 20px;
      cursor: pointer;
      display: none;
      &:hover {
        color: #409EFF;
      }
    }
    .el-input-group__prepend {
      width: 120px;
    }
    .el-table {
      tr:hover .operation-btn {
        display: inline-block;
      }
    }
  }
</style>
